﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Xunit;
using M3G;

namespace MyTestProject {
    public class TestTransformVectors {

        /**
         * TransformVectorsのテスト１
         * 4要素のベクトルの変換
         * */
        [Fact]
        public void TestTransformVectors1 () {
            var tra = new Transform (new float[]{1,2,0,0,
                                                 2,0,1,0,
                                                 1,1,1,1,
                                                 0,0,2,1});
            var vectors  = new float[] { 1, 2, 3, 4, 5, 6, 7, 8 };
            var expected = new float[] { 5, 5, 10, 10, 17, 17, 26, 22 };

            tra.TransformVectors (vectors);

            Assert.Equal (expected, vectors, new FloatComparere (0.0001f));
        }

        /**
         * TransformVectorsのテスト2
         * 3要素のベクトルの変換(w=1とみなしw除算された結果を受け取る)
         * */
        [Fact]
        public void TestTransformVectors2 () {
            var tra = new Transform (new float[]{1,2,0,0,
                                                 2,0,1,0,
                                                 1,1,1,1,
                                                 0,0,0,1});
            var vectors  = new float[] { 1, 2, 3, 4, 5, 6 };
            var expected = new float[] { 5, 5, 7, 14, 14, 16 };
        
            tra.TransformVectors3 (vectors, true);

            Assert.Equal (expected, vectors, new FloatComparere (0.0001f));
        }

        /**
         * TransformVectorsのテスト2
         * 3要素のベクトルの変換(w=0とみなす)
         * */
        [Fact]
        public void TestTransformVectors3 () {
            var tra = new Transform (new float[]{1,2,0,0,
                                                 2,0,1,0,
                                                 1,1,1,1,
                                                 0,0,0,1});
            var vectors  = new float[] { 1, 2, 3, 4, 5, 6 };
            var expected = new float[] { 5, 5, 6, 14, 14, 15 };

            tra.TransformVectors3 (vectors, true);

            Assert.Equal (expected, vectors, new FloatComparere (0.0001f));
        }


        /**
         * TransformVertexArrayのテスト1
         * 2コンポーネント(w=1)
         * */
        [Fact]
        public void TestTransformVertexArray1 () {
            var tra = new Transform (new float[]{1,2,0,0,
                                                 2,0,1,0,
                                                 1,1,1,1,
                                                 0,0,0,1});
            var varry = new VertexArray (2, 2, ArrayType.Short);
            var values = new ushort[] { 1, 2, 3, 65535 };
            varry.Set (0, 2, values);


            var expected = new float[] { 5, 2, 4, 1, 131073, 6, 65539, 1 };
            var vectors  = new float[8];

            tra.TransformVertexArray (varry, vectors, true);

            Assert.Equal (expected, vectors, new FloatComparere (0.0001f));
        }

        /**
         * TransformVertexArrayのテスト1
         * 2コンポーネント(w=0)
         * */
        [Fact]
        public void TestTransformVertexArray2 () {
            var tra = new Transform (new float[]{1,2,0,0,
                                                 2,0,1,0,
                                                 1,1,1,1,
                                                 0,0,0,1});
            var varry = new VertexArray (2, 2, ArrayType.Short);
            var values = new ushort[] { 1, 2, 3, 65535 };
            varry.Set (0, 2, values);


            var expected = new float[] { 5, 2, 3, 0, 131073, 6, 65538, 0 };
            var vectors  = new float[8];

            tra.TransformVertexArray (varry, vectors, false);

            Assert.Equal (expected, vectors, new FloatComparere (0.0001f));
        }


        [Fact]
        public void TestScale () {
            var tra = new Transform ();
            tra.PostScale (1, 2, 3);
            var vectors = new float[] { 1, 2, 3, 1 };
            var expected = new float[] { 1, 4, 9, 1 };
            
            tra.TransformVectors (vectors);
            
            Assert.Equal (expected, vectors);
        }

        [Fact]
        public void TestTranslate () {
            var tra = new Transform ();
            tra.PostTranslate (1, 2, 3);
            var vectors = new float[] { 1, 2, 3, 1 };
            var expected = new float[] { 2, 4, 6, 1 };

            tra.TransformVectors (vectors);

            Assert.Equal (expected, vectors, new FloatComparere (0.00001f));
        }

        [Fact]
        public void TestRotateZ () {
            var tra = new Transform ();
            tra.PostRotate (90, 0, 0, 1);
            var vectors = new float[] { 1, 0, 0, 1 };
            var expected = new float[] { 0, 1, 0, 1 };

            tra.TransformVectors (vectors);

            Assert.Equal (expected, vectors, new FloatComparere(0.00001f));
        }

        [Fact]
        public void TestRotateY () {
            var tra = new Transform ();
            tra.PostRotate (90, 0, 1, 0);
            var vectors = new float[] { 1, 0, 0, 1 };
            var expected = new float[] { 0, 0, -1, 1 };

            tra.TransformVectors (vectors);

            Assert.Equal (expected, vectors, new FloatComparere(0.00001f));
        }

        [Fact]
        public void TestRotateX () {
            var tra = new Transform ();
            tra.PostRotate (90, 1, 0, 0);
            var vectors = new float[] { 0, 0, -1, 1 };
            var expected = new float[] { 0, 1, 0, 1 };

            tra.TransformVectors (vectors);

            Assert.Equal (expected, vectors, new FloatComparere (0.00001f));
        }


    }
}
